package cn.fcj.f20240328.fsocket.server;

import cn.fcj.f20240328.fsocket.ReadDataEntity;
import cn.fcj.f20240328.fsocket.base.ISocketEventHandler;

import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static java.util.concurrent.TimeUnit.SECONDS;

public class SelectorsManager {
    private static final ExecutorService workPool = Executors.newFixedThreadPool( Runtime.getRuntime().availableProcessors());
    private SelectorThread[] multipleSelector;
    private int coreNum = 0;////获取处理器核心数
    private int index = 0;//分配任务索引
    public SelectorsManager(){
        coreNum = Runtime.getRuntime().availableProcessors();
        System.out.println("----------FNIOSocketServer......cpu 核心数:"+coreNum);
        if (coreNum == 0) {
            coreNum = 4;
        } else {
            multipleSelector = new SelectorThread[coreNum];
        }
        for (int i = 0; i < coreNum; i++) {
            multipleSelector[i] = new SelectorThread();
            startWorkPool(multipleSelector[i]);
        }
//        startWorkPool();
    }
    public SelectionKey acceptAndRegister(SelectionKey key,Map<String,SelectionKey> clients){
        try {
            //1.当前通道在init方法中注册到了selector中的ServerSocketChannel
            ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
            //2.阻塞方法, 客户端发起后请求返回.
            SocketChannel channel = serverSocketChannel.accept();
            ///3.serverSocketChannel设置为非阻塞
            channel.configureBlocking(false);
            SelectorThread multipleReactor;
            multipleReactor = multipleSelector[index % coreNum];
            index = (index + 1) % coreNum;
            multipleReactor.wakeup();
//            Thread.sleep(5000);
            long start=System.currentTimeMillis();
            System.out.println("===register========ip:"+ReadDataEntity.getChannelIP(channel));
            System.out.println("===register========Time:"+start);
            SelectionKey newkey= multipleReactor.registerEvnet(channel,SelectionKey.OP_READ);
            clients.put(ReadDataEntity.getChannelIP(channel),newkey);
            long end=System.currentTimeMillis();
            System.out.println("=register======1tiem:"+end+"===用时=:"+(end-start));
            return newkey;
        } catch (IOException e) {
        }
        return null;
    }
    public  void setSocketEventHandler(ISocketEventHandler socketEventHandler) {
        if (socketEventHandler != null) {
            for (SelectorThread selectorThread : multipleSelector) {
                selectorThread.setSocketEventHandler(socketEventHandler);
            }
        }
    }

    public void stopWorkPool()  {
        try {
            for(SelectorThread selectorThread:multipleSelector){
                selectorThread.stopSocket();
            }
            workPool.shutdown();
            if(!workPool.awaitTermination(2, SECONDS)){
                //如果等待一段时间后还有任务在执行中被中断或者有任务提交了未执行
                workPool.shutdownNow();
            }
        }catch (InterruptedException interruptedException){
            workPool.shutdownNow();
        }
    }
    public void startWorkPool(SelectorThread selectorThread){
        selectorThread.setRuning(true);
        workPool.execute(selectorThread);
    }
    public void startWorkPool(){
        for(SelectorThread selectorThread:multipleSelector){
            selectorThread.setRuning(true);
            workPool.execute(selectorThread);
        }
    }
}
